package br.com.iswe.core.security.acegisecurity;

import java.util.Iterator;

import javax.persistence.Transient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.Authentication;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.ConfigAttributeDefinition;

@SuppressWarnings("unchecked")
public class RoleVoter extends org.springframework.security.vote.RoleVoter {

	protected transient Log log = getLog();
    @Transient
	protected Log getLog() {
        return LogFactory.getLog(RoleVoter.class);
    }
	
	
	public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config) {
		int result = ACCESS_ABSTAIN;
		Iterator iter = config.getConfigAttributes().iterator();
		
		StringBuilder logMessage = new StringBuilder("RoleVoter vote() Papeis requisitados pelo Objeto: ");
		if(log.isDebugEnabled()){
			logMessage.append( config.toString() );
			logMessage.append( " User ROLES: " );
		}
		
		boolean usersRoles = false;
		while (iter.hasNext()) {
			ConfigAttribute attribute = (ConfigAttribute) iter.next();

			if (this.supports(attribute)) {
				result = ACCESS_DENIED;

				// Attempt to find a matching granted authority
				for (int i = 0; i < authentication.getAuthorities().length; i++) {
					if(log.isDebugEnabled()){
						if(!usersRoles){
							logMessage.append( authentication.getAuthorities()[i].getAuthority() );
							logMessage.append( ", " );
						}
					}
					if (attribute.getAttribute().equals(
							authentication.getAuthorities()[i].getAuthority())) {
						
						if(log.isDebugEnabled()){
							logMessage.append(" ROLE Found :  ACCESS_GRANTED");
							log.debug(logMessage.toString());
						}
						
						return ACCESS_GRANTED;
					}
				}
			}
			usersRoles = true;
		}
		if(log.isDebugEnabled()){
			logMessage.append(" ROLE Not Found -> ");
			if(result == ACCESS_DENIED){
				logMessage.append(" ACCESS_DENIED ");
			}
			else{
				logMessage.append(" ACCESS_ABSTAIN ");
			}
			log.debug(logMessage.toString());
		}
		return result;
	}

}
